home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / cug190.zip / BC.C < prev    next >
Text File  |  1985-11-15  |  17KB  |  861 lines

  1. /******************************************************************
  2.     bc.c, code building function of as68 assembler
  3. */
  4.  
  5. /*        (C) Copyright 1982 Steve Passe        */
  6. /*        All Rights Reserved                    */
  7.  
  8. /* version 1.00 */
  9. /* created 10/21/82 */
  10.  
  11. /* version 1.01
  12.  
  13.     8/30/83    ver. 1.01 modified for Aztec ver. 1.05g    smp
  14.  
  15. */
  16.  
  17. /* begincode */
  18.  
  19. /* includes */
  20.  
  21. #define AZTECZII 1
  22.  
  23. #ifndef AZTECZII
  24. #include <stdio.h>
  25. #else
  26. #include "stdio.h"                                /* with aztecII compiler */
  27. #endif
  28. #include "b:as68.h"
  29.  
  30. /* externals */
  31.  
  32. extern char pass;                            /* present pass number, 1 or 2 */
  33. extern unsigned line_count;                    /* line number of source file */
  34. extern long loc_counter;                    /* address to assemble obj code */
  35. extern int loc_plus;                        /* increment to loc counter */
  36. extern FLAG abs_long;                        /* default to absolute long add.*/
  37. extern FLAG rorg;                            /* in pc relative mode */
  38. extern char label[32];                    /* buffer for label from preparse */
  39. extern char instr[33];                    /* buffer for mnem, psdo or macro */
  40.  
  41. extern struct _mtable mtable[];                /* mnemonic lookup table */
  42. extern struct _mvalue mvalue[];                /* mnemonic code table */
  43. extern struct _oprnd op1, op2;                /* structs to hold operand val */
  44. extern char code[];                            /* code array */
  45.  
  46. p1_mnem(mt)
  47. struct _mtable *mt;
  48. {
  49.     int result, index;
  50.  
  51.     if ((index = match(mt)) == ERROR) {
  52. /** flush error stack someday? */
  53.         return ERROR;
  54.     }
  55.     switch (result = mvalue[index]._opc_len) {    /* determine code length... */
  56.     case 1:
  57.     case 2:
  58.     case 3:
  59.         break;
  60.     case 12:                                /* _imd not contained in opcode */
  61.     case 13:
  62.         result -= 10;                        /* strip '10' flag */
  63.         result += p1_codelen(&op2);            /* add second operand length */
  64.         break;
  65.     case 0:                                        /* gotta figure it out */
  66.         if (/**rorg**/ op1._rel_lbl && mvalue[index]._optyp1 == _sadr
  67.             && (op1._typ == _address || op1._typ == _d16_ani)) {
  68.             result = 2 + p1_codelen(&op2);        /* 1 for opcode, 1 for raddr */
  69.         }
  70.         else result = p1_codelen(&op1) + p1_codelen(&op2) + 1; /* 1 for code */
  71.         break;
  72.     }
  73.     loc_plus = result * 2;
  74.     return result;
  75. }
  76.  
  77. p1_codelen(op)
  78. struct _oprnd *op;
  79. {
  80.     int result;
  81.  
  82.     switch (op->_typ) {
  83.     case _address:
  84.         result = (op->_long_val) ? 2 : 1;
  85.         break;
  86.     case _d16_ani:
  87.     case _d8_anx:
  88.     case _labeli:
  89.     case _reglst:
  90.     case _label:    /* needed? */
  91.         result = 1;
  92.         break;
  93.     default:
  94.         result = 0;
  95.     }
  96.     return result;
  97. }
  98.  
  99. p2_mnem(mt)
  100. struct _mtable *mt;
  101. {
  102.     register int x;                                    /* scratch */
  103.     int index        ;                                /* index to mvalue */
  104.     int result;
  105.  
  106.     for (x = 0; x < 10; ++x) {            /* init code array to 0 */
  107.         code[x] = 0;
  108.     }
  109.     if ((index = match(mt)) == ERROR) {
  110.         dump_code(CODE, code, 0);
  111.         return ERROR;
  112.     }
  113.     code[0] = mvalue[index]._opcb1;                            /* get opcode */
  114.     code[1] = mvalue[index]._opcb2;                            /* get opcode */
  115.  
  116.     if ((result = (*mvalue[index]._p2_action)()) < 0) {        /* call funct */
  117.         err_out(result);
  118.         loc_plus = 0;
  119.     }
  120.     else loc_plus = ++result * 2;                    /* bytes created */
  121.     dump_code(CODE, code, loc_plus);                /* send them */
  122.     return result;                                    /* words created */
  123. }
  124.  
  125. match(mt)
  126. struct _mtable *mt;
  127. {
  128.     int index;                                        /* index to mvalue */
  129.     int type1, type2;                        /* operand types */
  130.  
  131.     if ((type1 = op_eval(&op1)) < 0) {                /* legal type found? */
  132.         err_out(BAD_OP1);            /* first op bad */
  133.     }
  134.     if ((type2 = op_eval(&op2)) < 0) {                /* second op? */
  135.         err_out(BAD_OP2);            /* no good */
  136.     }
  137.     if (type1 < 0 || type2 < 0) {
  138.         return ERROR;                            /* use NULL opcode */
  139.     }
  140.     if ((index = type_search(mt, type1, type2)) <=0) {
  141.         switch (index) {
  142.         case ILGL_OP1:
  143.             err_out(ILGL_OP1);            /* no good */
  144.             return ERROR;
  145.         case ILGL_OP2:
  146.             err_out(ILGL_OP2);            /* no good */
  147.             return ERROR;
  148.         default:
  149.             return ERROR;
  150.         }
  151.     }
  152.     return index;
  153. }
  154.  
  155. type_search(mt, type1, type2)
  156. struct _mtable *mt;
  157. int type1;
  158. int type2;
  159. {
  160.     register int x, y;                                /* count and index */
  161.     char t1, t2;                                    /* temp for array value */
  162.  
  163.     for (x = mt->_mvc, y = mt->_mvi; x; --x, ++y) {    /* search */
  164.                                             /* find op1 match... */
  165.         if (((t1 = mvalue[y]._optyp1) == type1)        /* if exact match */
  166.         || ((!(t1 & ~0xf0)) && (t1 & type1))) {    /* or classtyp and match */
  167.                                             /* search for second match */
  168.             for ( ; (mvalue[y]._optyp1 == t1) && x; --x, ++y) {
  169.                 if (((t2 = mvalue[y]._optyp2) == type2)    /* 2nd matches */
  170.                 || ((!(t2 & ~0xf0)) && (t2 & type2))) {    /* or typ & match */
  171.                     return y;                                /* found a match */
  172.                 }
  173.             }
  174.             return ILGL_OP2;
  175.         }
  176.     }
  177.     return ILGL_OP1;
  178. }
  179.  
  180.  
  181.  
  182. /* mask 3 bit immediate data from op1 over bits 3-1 of code [0] */
  183.  
  184. bbb(op)
  185. struct _oprnd *op;
  186. {
  187.     if (op->_data & ~7) return ERR_BBB;
  188.     code[0] |= (op->_data << 1);
  189.     return NULL;
  190. }
  191.  
  192. /* first ext word holds bit number (7/31) from first operand */
  193.  
  194. bbbx(size, op)
  195. int size;
  196. struct _oprnd *op;
  197. {
  198.     switch (size) {
  199.     case 3:
  200.         if (op->_data & ~7L) return ERR_BX3;                    /* range? */
  201.     case 5:
  202.         if (op->_data & ~31L) return ERR_BX5;
  203.         code[3] = op->_data;
  204.         return 1;                                            /* 1 ext word */
  205.     default:
  206.         return ERR_BX;
  207.     }
  208. }
  209.  
  210. /** mask bits 3-1 of first byte with op1, 8 = 00 */
  211.  
  212. ccc(op)
  213. struct _oprnd *op;
  214. {
  215.     if (op->_data < 1L || op->_data > 8L) return ERR_CCC;
  216.     code[0] |= (op->_data << 1) & 0x0f;
  217. /**    if (op->_data != 8L) code[0] |= op->_data << 1; **/
  218.  
  219.     return NULL;                                    /* no words added */
  220. }
  221.  
  222. /* mask bits 3-1 of first byte, or bits 2-0 of second, with op reg */
  223.  
  224. rsd(byt, op)
  225. int byt;
  226. struct _oprnd *op;
  227. {
  228.     code[byt] |= (byt) ? op->_reg : op->_reg << 1;
  229.     return NULL;
  230. }
  231.  
  232. /* register mask list from op into ext */
  233.  
  234. mmkk(order, op)
  235. char order;
  236. struct _oprnd *op;
  237. {
  238.     register int x;
  239.     unsigned u1 = 0;
  240.     unsigned m1 = 0x0001;
  241.     unsigned m2 = 0x8000;
  242.  
  243.     switch (order) {
  244.     case '>':
  245.         code[2] = op->_reg_list >> 8;                        /* high byte */
  246.         code[3] = op->_reg_list;                            /* low byte */
  247.         return 1;
  248.     case '<':
  249.  
  250.         for (x = 15; x >= 0; --x) {
  251.             u1 |= (op->_reg_list & (m1 << x)) ? (m2 >> x) : 0;
  252.         }
  253.  
  254.         code[2] = u1 >> 8;                        /* high byte */
  255.         code[3] = u1;                            /* low byte */
  256.         return 1;
  257.     default:
  258.         return ERR_MK;
  259.     }
  260. }
  261.  
  262. /* combined e, f, g, h, and j routines, 12/4/82 */
  263.  
  264. efghj(arg, i, op)
  265. char arg;
  266. int i;
  267. struct _oprnd *op;
  268. {
  269.     int len, displ;
  270.  
  271.     switch (op->_typ) {
  272.     case _ani:                                /* (an) */
  273.         if (arg == 'g') {
  274.             code[0] |= (op->_reg << 1);
  275.             code[1] |= 0x80;
  276.         }
  277.         else {
  278.             code[1] |= (0x10 | op->_reg);
  279.         }
  280.         return NULL;
  281.     case _pd_ani:                                /* -(an) */
  282.         switch (arg) {
  283.         case 'g':
  284.             code[0] |= (0x01 | op->_reg << 1);
  285.             return NULL;
  286.         case 'j': return ERR_J;
  287.         case 'h': return ERR_H;
  288.         default:
  289.             code[1] |= (0x20 | op->_reg);
  290.             return NULL;
  291.         }
  292.  
  293.     case _ani_pi:                                /* (an)+ */
  294.         switch (arg) {
  295.         case 'g':
  296.             code[0] |= (op->_reg << 1);
  297.             code[1] |= 0xc0;
  298.             return NULL;
  299.         case 'j': return ERR_J;
  300.         case 'h': return ERR_H;
  301.         default:
  302.             code[1] |= (0x18 | op->_reg);
  303.             return NULL;
  304.         }
  305.  
  306.     case _d16_ani:                                /* d16(an) */
  307.         switch (arg) {
  308.         case 'e':
  309.         case 'j':
  310.             if (/**rorg**/ op->_rel_lbl) {
  311.                 op->_ireg = op->_reg;                /* reg is an index */
  312.                 op->_iregtyp = op->_regtyp;            /* move type */
  313.                 op->_displ -= (loc_counter + 2);    /* make pc relative */
  314.                 code[1] |= 0x3b;
  315.                 return _d8_i(i, op);                /* indexed label */
  316.             }
  317.             break;
  318.         case 'g':
  319.             code[0] |= (0x01 | op->_reg << 1);
  320.             code[1] |= 0x40;
  321.             return _d16(i, op);
  322.         }
  323.         code[1] |= (0x28 | op->_reg);
  324.         return _d16(i, op);
  325.  
  326.     case _d8_anx:                                /* d8(an,i) */
  327.         if (arg == 'g') {
  328.             code[0] |= (0x01 | op->_reg << 1);
  329.             code[1] |= 0x80;
  330.         }
  331.         else {
  332.             code[1] |= (0x30 | op->_reg);
  333.         }
  334.         return _d8_i(i, op);
  335.  
  336.     case _address:        /* abs. add., short or long, or label if _rel_lbl */
  337.         switch (arg) {
  338.         case 'e':
  339.         case 'j':
  340.             if (/**rorg**/ op->_rel_lbl) {
  341.                 code[1] |= 0x3a;
  342.                 op->_displ = op->_addr - (loc_counter + 2);    /* rel. to pc */
  343.                 return _d16(i, op);                        /* finish as 'label' */
  344.             }
  345.             break;
  346.         case 'g':
  347.             code[1] |= 0xc0;
  348.             if (op->_long_val) {
  349.                 code[0] |= 0x03;
  350.                 code[i++] = op->_addr >> 24;
  351.                 code[i++] = op->_addr >> 16;
  352.                 len = 2;
  353.